package com.tn.service.dwr;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.googlecode.objectify.NotFoundException;
import com.tn.bo.Address;
import com.tn.bo.ClientSupplierData;
import com.tn.bo.Company;
import com.tn.bo.UserLoginDetails;
import com.tn.bo.UserProfile;
import com.tn.bo.UserProfileCurrentProperties;
import com.tn.bo.UserRegMapping;
import com.tn.dao.CompanyDAO;
import com.tn.dao.UserDAO;
import com.tn.util.MailService;
import com.tn.xfer.DwrResponse;
import com.tn.xfer.Registration;

public class RegisterDwr {
	public DwrResponse registerCompany(String userId, Registration reg){
		DwrResponse dwrResponse = new DwrResponse("REGISTER", 0);
		try{
		UserDAO uDao = new UserDAO();
		Long userId1 = Long.parseLong(userId);
		UserProfile userProfile = uDao.getUserProfile(userId1);
		Company company = new Company();
		company.setCompanyABuyer("Y");
		company.setCompanyASupplier("N");
		company.setCompanyName(reg.getCompanyName());
		company.setCompanyDomain(reg.getCompanyLOB());
		company.setCompanyTaxId(reg.getCompanyTaxId());
		company.setCompanySSN(reg.getCompanySsn());
		company.setAddressLine1(reg.getCompanyaddressLine1());
		company.setAddressLine2(reg.getCompanyaddressLine2());
		company.setContact(reg.getCompanyContact());
		company.setCity(reg.getCompanyCity());
		company.setState(reg.getCompanyState());
		company.setZip(reg.getCompanyZip());
		company.setPhone(reg.getCompanyPhoneNumber());
		company.setFax(reg.getCompanyFaxNumber());
		
		company.setEmail(reg.getCompanyEmail());
		company.setCountry(reg.getCompanyCountry());
		company.setURL(reg.getCompanyURL());
		company.setCurrency(reg.getCompanyCurrency());
		
		Address defaultLocation = new Address();
		defaultLocation.setAddressLine1(reg.getCompanyaddressLine1());
		defaultLocation.setAddressLine2(reg.getCompanyaddressLine2());
		defaultLocation.setCity(reg.getCompanyCity());
		defaultLocation.setState(reg.getCompanyState());
		defaultLocation.setZip(reg.getCompanyZip());
		defaultLocation.setBillingAddress("Y");
		defaultLocation.setShippingAddress("Y");
		defaultLocation.setLocationId(String.valueOf(System.currentTimeMillis()));
		
		company.setOtherRegId(reg.getOtherRegId());
		company.setOtherRegvalue(reg.getOtherRegvalue());
		company.setPaymentTerms(reg.getCompanyPaymentTerms());
		
		company.setLocations(new ArrayList<Address>());
		company.getLocations().add(defaultLocation);
	
		//regXfer.companyPaymentTerms = dwr.util.getValue("reg_compPaymentTerms");TODO:payment terms
		
		CompanyDAO cDao = new CompanyDAO();
		company = cDao.insertCompany(company);
		userProfile.setCompanyId(company.getCompanyId());
		uDao.updateUser(userProfile);
			
		//User registered, if he/she is the first or second user, set the user as admins for the company.
		if(company.getCompanyProfileAdmins() == null || company.getCompanyProfileAdmins().isEmpty()
				|| company.getCompanyProfileAdmins().size() < 2){
			if(company.getCompanyProfileAdmins() == null){
				company.setCompanyProfileAdmins(new ArrayList<String>());
			}
			
			company.getCompanyProfileAdmins().add(userProfile.getUserProfileId().toString());
			cDao.updateCompany(company);
		}
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	//TODO: Password update is remaining.
	public DwrResponse registerUser(Registration reg){
		DwrResponse dwrResponse = new DwrResponse("REGISTER", 0);
		
		
		UserProfile profile = new UserProfile();
		profile.setFirstName(reg.getFname());
		profile.setLastName(reg.getLname());
		profile.setEmailAddress(reg.getEmail());
		profile.setAddressLine1(reg.getAddressLine1());
		profile.setAddressLine2(reg.getAddressLine2());
		profile.setCity(reg.getCity());
		profile.setState(reg.getState());
		profile.setZip(reg.getZip());
		profile.setWorkPhone(reg.getWorkPhone());
		profile.setFax(reg.getFax());
		profile.setCountry(reg.getCountry());
		profile.setDeliveryInfo(reg.getDeliveryInfo());
		profile.setIsVerified("false");
		profile.setSalutation(reg.getSalutation());
		
		
		UserDAO uDao = new UserDAO();
		UserLoginDetails login = new UserLoginDetails();
		login.setUserId(reg.getUserName());
		login.setPlainTextPassword(reg.getPassword());
		login.setUserPasswordHash(UserLoginDetails.createUserPasswordHash(login));
		try{
			long userId = uDao.registerUser(profile, login);
			MailService mailService = new MailService();
			
			//Get Registration Hash and persist it.
			String regHash = UserLoginDetails.createRegistrationHash(String.valueOf(userId));
			UserRegMapping mapping = new UserRegMapping();
			mapping.setRegHash(regHash);
			mapping.setUserId(String.valueOf(userId));
			mapping.setStatus(UserRegMapping.STATUS_UNUSED);
			uDao.saveUserRegMapping(mapping);
			mailService.sendRegMail(reg.getEmail(), regHash);
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	
	public DwrResponse checkUserIdAvailable(String userId){
		DwrResponse resp = new DwrResponse("CHECK_USERID_EXISTS",0);
		if(new UserDAO().findUserByUserId(userId) != null){
			resp.setRespCode(-1);
		}
		
		return resp;
	}
	
	public DwrResponse findCompany(String companyName){
		DwrResponse resp = new DwrResponse("FIND_COMPANY",0);
		CompanyDAO dao = new CompanyDAO();
		List<Company> list = dao.findCompanyByNamePattern(companyName);
		resp.setObjRespOrError(list);
		return resp;
	}
	
	//TODO this will get changed when we change search criteria.
	public DwrResponse searchCompany(String companyName){
		DwrResponse resp = new DwrResponse("FIND_COMPANY",0);
		CompanyDAO dao = new CompanyDAO();
		List<Company> list = dao.findCompanyByNamePattern(companyName);
		resp.setObjRespOrError(list);
		return resp;
	}
	
	public DwrResponse addRemovePreferredSuplierList(String usrcompany_id,List<String> supplierIdList,String action){
		DwrResponse dwrResponse = new DwrResponse("Add_SUPPLIER",0);
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(usrcompany_id);
		
		try{
			for(String sid: supplierIdList){
				//construct id and retrieve mapping.
				String id = usrcompany_id + "|" + sid;
				
				ClientSupplierData data = null;
				try{
					
					data = cDao.findAssociation(id);
					if(data != null){
						if("DELETE".equals(action)){
							//Delete
							data.setAssoStatus("DELETED");
							cDao.updateAssociation(data);
							company.getSupplierIds().remove(sid);
						}else{
							if(company.getSupplierIds() == null){
								company.setSupplierIds(new ArrayList<String>());
							}
							if(!company.getSupplierIds().contains(sid)){
								company.getSupplierIds().add(sid);
							}
						}
					}
				}catch(NotFoundException nfe){
					data = new ClientSupplierData();
					data.setMappingId(id);
					data.setClientId(usrcompany_id);
					data.setSupplierId(sid);
					data.setAssoStatus("NEW");
					cDao.insertAssociation(data);
					if(company.getSupplierIds() == null){
						company.setSupplierIds(new ArrayList<String>());
					}
					if(!company.getSupplierIds().contains(sid)){
						company.getSupplierIds().add(sid);
					}
				}
				
			}
			
			cDao.updateCompany(company);
			dwrResponse = getPreferredSuplierList(usrcompany_id);
		}
		catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		return dwrResponse;
		
	}
	
	public DwrResponse getPreferredSuplierList(String usrcompany_id){
		DwrResponse dwrResponse = new DwrResponse("Add_SUPPLIER",0);
		CompanyDAO cDao = new CompanyDAO();
		Company company = null;
		try{
			if(StringUtils.isNotEmpty(usrcompany_id) ){
				company = cDao.findCompanyByCompanyId(usrcompany_id);
				List<Company> supplierList = cDao.findSupplierByCompanyId(usrcompany_id);
				dwrResponse.setObjRespOrError(supplierList);
			}
		}
		catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		return dwrResponse;
		
	}
	
	public DwrResponse getClientsList(String companyId){
		DwrResponse dwrResponse = new DwrResponse("GET_CLIENTS",0);
		CompanyDAO cDao = new CompanyDAO();
		Company company = null;
		List<Company> ret = new ArrayList<Company>(); 
		
		try{
			List<ClientSupplierData> asson = cDao.findAssonBySupplier(companyId);
			if(asson != null){
				for(ClientSupplierData mapping: asson){
					if(companyId.equals(mapping.getSupplierId())){
						 company = cDao.findCompanyByCompanyId(mapping.getClientId());
						 company.setAssoStatus(mapping.getAssoStatus());
						 ret.add(company);
					}
				}
			}
			dwrResponse.setObjRespOrError(ret);
		}
		catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		return dwrResponse;
		
	}
	//TODO: remove association of user from other company if it exists.
	public DwrResponse associateUserToCompany(String userId, String companyId){
		DwrResponse dwrResponse = new DwrResponse("REGISTER", 0);
		try{
		UserDAO uDao = new UserDAO();
		Long userId1 = Long.parseLong(userId);
		UserProfile userProfile = uDao.getUserProfile(userId1);
		
		
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(companyId);
		userProfile.setCompanyId(company.getCompanyId());
		uDao.updateUser(userProfile);
			
		//User registered, if he/she is the first or second user, set the user as admins for the company.
		if(company.getCompanyProfileAdmins() == null || company.getCompanyProfileAdmins().isEmpty()
				|| company.getCompanyProfileAdmins().size() < 2){
			if(company.getCompanyProfileAdmins() == null){
				company.setCompanyProfileAdmins(new ArrayList<String>());
			}
			
			company.getCompanyProfileAdmins().add(userProfile.getUserProfileId().toString());
			cDao.updateCompany(company);
			
			//Make this user a super user with all accesses.
			userProfile.setCurrentProperties(new UserProfileCurrentProperties());
				userProfile.getCurrentProperties().setId(
						(userId + "|" + companyId + "|" + String.valueOf(Math.round(Math.random()*1000))));
			//userProfile.getCurrentProperties().giveAllAccesses();
			uDao.updateUser(userProfile);
		}
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	
	public DwrResponse associateNonAdminUserToCompany(String userId, String companyId){
		DwrResponse dwrResponse = new DwrResponse("REGISTER", 0);
		try{
		UserDAO uDao = new UserDAO();
		Long userId1 = Long.parseLong(userId);
		UserProfile userProfile = uDao.getUserProfile(userId1);
		
		
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(companyId);
		userProfile.setCompanyId(company.getCompanyId());
		userProfile.setIsVerified("false");
		uDao.updateUser(userProfile);
			
		//send approval request to admin of this companyId
		sendApprovalMail(userProfile,companyId);
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	
	public void sendApprovalMail(UserProfile newuserProfile,String companyId){
		DwrResponse dwrResponse = new DwrResponse("UserProfile", 0);
		try{
		UserDAO uDao = new UserDAO();
		MailService ms = new MailService();
		
		
		
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(companyId);
		List<String> userProfileIds = company.getCompanyProfileAdmins();
		for(int i=0; i<userProfileIds.size();i++){
			UserProfile userProfile = uDao.getUserProfile(Long.parseLong(userProfileIds.get(i)));
			ms.sendApprovalMail(userProfile.getEmailAddress(),newuserProfile);
		}
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		
	}
	
	//TODO: remove association of user from other company if it exists.
	public DwrResponse getAdminUserForCompany(String companyId){
		DwrResponse dwrResponse = new DwrResponse("UserProfile", 0);
		try{
		UserDAO uDao = new UserDAO();
		
		
		
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(companyId);
		List<String> userProfileIds = company.getCompanyProfileAdmins();
		List<UserProfile> userProfileList = new ArrayList<UserProfile>();
		for(int i=0; i<userProfileIds.size();i++){
			UserProfile userProfile = uDao.getUserProfile(Long.parseLong(userProfileIds.get(i)));
			userProfileList.add(userProfile);
		}
		dwrResponse.setObjRespOrError(userProfileList);
		
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	public DwrResponse updateAssociation(List<ClientSupplierData> list){
		DwrResponse dwrResponse = new DwrResponse("UPD_ASSO", 0);
		try{
		CompanyDAO cDao = new CompanyDAO();
		for(ClientSupplierData data: list){
			List<ClientSupplierData> asson = cDao.findAssonBySupplierClient(data.getSupplierId(), data.getClientId());
			
			if(asson != null){
				ClientSupplierData assond = asson.get(0);
				assond.setAssoStatus(data.getAssoStatus());
				assond.setLastUpdateDate(new Date());
				cDao.updateAssociation(assond);
			}
		}
		
		
		
		
		dwrResponse.setObjRespOrError(this.getClientsList(list.get(0).getSupplierId()));
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	public DwrResponse getUserProfile(String username){
		DwrResponse resp = new DwrResponse("GET_USER_PROFILE",0);
		try{
		
		Long userId = Long.parseLong(username);
		UserDAO uDao = new UserDAO();
		UserProfile userProfile = uDao.getUserProfile(userId);
		resp.setObjRespOrError(userProfile);
		
		}catch(Exception ex){
			ex.printStackTrace();
			resp.setRespCode(-1);
			resp.setErrorMessage(ex.getMessage());
		}
		return resp;
	}
	
	public DwrResponse updateUser(Registration reg,String userId){
		DwrResponse dwrResponse = new DwrResponse("REGISTER", 0);
		UserDAO uDao = new UserDAO();
		Long userId1 = Long.parseLong(userId);
		UserProfile profile = uDao.getUserProfile(userId1);
		profile.setFirstName(reg.getFname());
		profile.setLastName(reg.getLname());
		//profile.setEmailAddress(reg.getEmail());
		profile.setAddressLine1(reg.getAddressLine1());
		profile.setAddressLine2(reg.getAddressLine2());
		profile.setCity(reg.getCity());
		profile.setState(reg.getState());
		profile.setZip(reg.getZip());
		profile.setWorkPhone(reg.getWorkPhone());
		profile.setFax(reg.getFax());
		profile.setCountry(reg.getCountry());
		profile.setDeliveryInfo(reg.getDeliveryInfo());
		//profile.setIsVerified("false");
		
		try{
			uDao.updateUser(profile);
			profile = uDao.getUserProfile(userId1);
			dwrResponse.setObjRespOrError(profile);
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setErrorMessage(ex.getMessage());
		}
		
		return dwrResponse;
	}
	
	
	public String sendForgotPasswordMail(String username){
		String message = "Username Does not exist";
		UserDAO uDao = new UserDAO();
		UserLoginDetails details = uDao.findUserByUserId(username);
		UserProfile userProfile = uDao.getUserProfile(details
				.getUserProfileId());
		if(details != null){
			
			MailService ms = new MailService();
			try {
				//Get Registration Hash and persist it.
				String fpwdHash = UserLoginDetails.createRegistrationHash(String.valueOf(username));
				UserRegMapping mapping = new UserRegMapping();
				mapping.setRegHash(fpwdHash);
				mapping.setUserId(username);
				mapping.setStatus(UserRegMapping.STATUS_UNUSED);
				uDao.saveUserRegMapping(mapping);
				ms.sendForgotPasswordMail(userProfile.getEmailAddress(), fpwdHash);
				message = "Email Sent Successfully";
			} catch (Exception e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				message = "Error Sending Mail.Please Contact Admin";
			}
			
			
		}
		
		return message;
	}
	
	
	public DwrResponse updateCompany(String companyId, Registration reg){
		DwrResponse dwrResponse = new DwrResponse("UPDATE COMPANY", 0);
		
		try{
		CompanyDAO cDao = new CompanyDAO();
		Company company = cDao.findCompanyByCompanyId(companyId);	
		dwrResponse.setObjRespOrError(company);
		company.setCompanyABuyer("Y");
		company.setCompanyASupplier("N");
		company.setCompanyName(reg.getCompanyName());
		company.setCompanyDomain(reg.getCompanyLOB());
		company.setCompanyTaxId(reg.getCompanyTaxId());
		company.setCompanySSN(reg.getCompanySsn());
		company.setAddressLine1(reg.getCompanyaddressLine1());
		company.setAddressLine2(reg.getCompanyaddressLine2());
		company.setContact(reg.getCompanyContact());
		company.setCity(reg.getCompanyCity());
		company.setState(reg.getCompanyState());
		company.setZip(reg.getCompanyZip());
		company.setPhone(reg.getCompanyPhoneNumber());
		company.setFax(reg.getCompanyFaxNumber());
		
		company.setEmail(reg.getCompanyEmail());
		company.setCountry(reg.getCompanyCountry());
		company.setURL(reg.getCompanyURL());
		company.setCurrency(reg.getCompanyCurrency());
		
		
		
		company.setOtherRegId(reg.getOtherRegId());
		company.setOtherRegvalue(reg.getOtherRegvalue());
		company.setPaymentTerms(reg.getCompanyPaymentTerms());
		dwrResponse.setObjRespOrError(company);
		
		company.setEmailPreferences(reg.getEmailPreferences());
		company.setFaxPreferences(reg.getFaxPreferences());
		cDao.updateCompany(company);
		
		company = cDao.findCompanyByCompanyId(companyId);
		dwrResponse.setObjRespOrError(company);
		
		}catch(Exception ex){
			ex.printStackTrace();
			dwrResponse.setRespCode(-1);
			dwrResponse.setObjRespOrError(companyId+ex.toString());
		}
		
		return dwrResponse;
	}
	
	
}
